const mongoose = require('mongoose');
const xlsx = require('xlsx'); 
const Schema = mongoose.Schema;
const { escapeRegex } = require('@/utils');

// 操作日志模型
const auditLogSchema = new Schema({
  admin_id: { 
    type: Schema.Types.ObjectId, 
    ref: 'Admin',
    required: true 
  },
  action: { type: String, required: true },
  target: String,
  ip_address: String,
  timestamp: { type: Date, default: Date.now },
  execution_time: Number,
  request_data: Object,
  response_data: Object,
  response_status: Number,
  target_id: Schema.Types.ObjectId,
  // 操作前状态
  // before_state: Object,
  // 操作后状态
  // after_state: Object,
  is_sensitive: { type: Boolean, default: false }
});
auditLogSchema.statics.getLogs = async function (nickname, offset, limit) {
  try {
    const query = {};
    if (nickname) { 
      const { Admin } = require('./');
      const parentQuery = {};
      const escapedName = escapeRegex(nickname);
      parentQuery.nickname = { $regex: escapedName, $options: 'i' };
      const admins = await Admin.find(parentQuery).lean();
      if (admins.length === 0) return { total: 0, rows: [] };
      query.admin_id = { $in: admins.map(admin => admin._id) };
    }
    const [result] = await this.aggregate([
      // 1. 匹配查询条件
      { $match: query },

      // 2. 关联查询用户信息
      { $lookup: {
        from: 'admins', // 关联的集合名
        localField: 'admin_id', // 本地关联字段
        foreignField: '_id', // 关联集合的匹配字段
        as: 'admin_info' // 存储关联结果的字段名
      }},
      { $unwind: {
        path: '$admin_info',
        preserveNullAndEmptyArrays: true
      }},
      { $facet: {
        metadata: [{
          $count: 'total' // 统计符合条件的总文档数
        }],
        data: [
          // 投影需要的字段
          { $project: {
            _id: 1,
            operate: '$admin_info.nickname',
            action: 1,
            target: 1,
            ip_address: 1,
            timestamp: 1,
            execution_time: 1,
            request_data: 1,
            response_data: 1,
            response_status: 1,
            target_id: 1,
            is_sensitive: 1
          }},
          // 排序
          { $sort: { timestamp: -1 } },
          // 分页
          { $skip: Number(offset) },
          { $limit: Number(limit) }
        ]
      }},

      // 6. 整合结果
      { $unwind: '$metadata' },
      { $project: {
        rows: '$data',
        total: '$metadata.total'
      }}
    ]);
    // 处理没有结果的情况
    if (!result || !result.rows) {
      return { rows: [], total: 0 };
    }
    return result;
  } catch (error) {
    throw error;
  }
}
auditLogSchema.statics.deleteLog = async function (_id) {
  try {
    return await this.findByIdAndDelete(_id);
  } catch (error) {
    throw error;
  }
}
auditLogSchema.statics.exportLogs = async function (nickname) {
  try {
    const query = {};
    if (nickname) {
      const { Admin } = require('./');
      const parentQuery = {};
      const escapedNickname = escapeRegex(nickname);
      parentQuery.nickname = { $regex: escapedNickname, $options: 'i' };
      const admins = await Admin.find(parentQuery).lean();
      if (admins.length === 0) return { total: 0, rows: [] };
      query.admin_id = { $in: admins.map(admin => admin._id) };
    }
    const result = await this.aggregate([
      // 1. 匹配查询条件
      { $match: query },

      // 2. 关联查询用户信息
      { $lookup: {
        from: 'admins', // 关联的集合名
        localField: 'admin_id', // 本地关联字段
        foreignField: '_id', // 关联集合的匹配字段
        as: 'admin_info' // 存储关联结果的字段名
      }},
      { $unwind: {
        path: '$admin_info',
        preserveNullAndEmptyArrays: true
      }},
      { $project: {
         _id: 1,
        operate: '$admin_info.nickname',
        action: 1,
        target: 1,
        target_id: 1,
        ip_address: 1,
        timestamp: 1,
        execution_time: 1,
        request_data: 1,
        response_data: 1,
        response_status: 1,
      }},
    ]);
    const headerConfig = [
      { key: 'operate', header: '操作人' },
      { key: 'action', header: '操作类型' },
      { key: 'target', header: '目标' },
      { key: 'target_id', header: '目标ID' },
      { key: 'ip_address', header: 'IP地址' },
      { key: 'timestamp', header: '操作时间' },
      { key: 'execution_time', header: '执行时间' },
      { key: 'request_data', header: '请求数据' },
      { key: 'response_data', header: '响应数据' },
      { key: 'is_sensitive', header: '是否敏感' },
      { key: 'response_status', header: '响应状态' },
    ];
    const worksheet = xlsx.utils.json_to_sheet(
      result.map(item => headerConfig.reduce((obj, { key }) => {
        let value = item[key];
        if(key === 'response_data') obj[key] = value.data.replace(/\\/g, '');
        else if(key === 'request_data') obj[key] = JSON.stringify(value);
        else if(key === 'is_sensitive') obj[key] = value ? '是' : '否';
        else if(key === 'target_id') obj[key] = value?.toString() || '';
        else obj[key] = value;
        return obj;
      }, {})),
      // 指定表头顺序及名称
      { header: headerConfig.map(h => h.key) }
    );
    headerConfig.forEach(({ key, header }, index) => {
      const cellAddress = xlsx.utils.encode_cell({ r: 0, c: index }); // 第1行（0-based索引）
      worksheet[cellAddress].v = header; // 将英文键名替换为中文表头
    });
    const workbook = xlsx.utils.book_new();
    xlsx.utils.book_append_sheet(workbook, worksheet, 'AuditLog');
    const buffer = xlsx.write(workbook, {
      bookType: 'xlsx',
      type: 'buffer', // 返回Buffer对象
    });
    return {buffer, filename: '操作日志.xlsx'};
  } catch (error) {
    console.log(error.message);
    throw error;
  }
}

module.exports = mongoose.model('AuditLog', auditLogSchema);
